<?php

declare(strict_types=1);

namespace App\Resource\Service;

use App\Common\Constants\ErrorCode;
use App\Common\Service\BaseService;
use App\Resource\Model\CategoryModel;
use App\Resource\Model\CrdCategoryModel;
use App\Resource\Model\GoodsModel;
use App\Third\Model\ShopLsyGoodsInfoModel;
use Hyperf\DbConnection\Db;
use Hyperf\Di\Annotation\Inject;
use function Symfony\Component\String\s;

class CategoryService extends BaseService
{

    /**
     * @Inject
     * @var CategoryModel
     */
    protected $categoryModel;

    /**
     * @Inject
     * @var CrdCategoryModel
     */
    protected $crdCategoryModel;

    /**
     * @Inject
     * @var GoodsModel
     */
    protected $goodsModel;

    /**
     * @param array $where
     * @param int $perPage
     * @param array|string[] $field
     *
     * @return array
     */
    public function getList(array $where, int $perPage = 100, array $field = ['*'])
    {
        $shopType = $where['shop_type'] ?? null;
        if($shopType == 1){
            //次日达
            $query = $this->crdCategoryModel::query();
        }elseif($shopType == 2){
            //龙收银分类
            return $this->lsyClassName();
        }else{
            //普通商城
            $query = $this->categoryModel::query();
        }

        !empty($where['title']) && $query->whereRaw('INSTR(title, ?) > 0', [$where['title']]);
        $query->where('is_deleted', '=', 0);
        $list = $query->select($field)->orderBy('sort', 'asc')->get();
        if (!$list -> isEmpty()) {
            $cateIdsArr = array_unique(array_column($list->toArray(), 'id'));
        } else {
            return ['code' => ErrorCode::SUCCESS, 'data' => $list];
        }
        // 计算分类下商品数量
        $goodsCountArr = $this -> calculateNumOfGoods($cateIdsArr, $shopType);
        foreach ($list as $key => $val) {
            $list[$key]['count'] = $goodsCountArr[$val['id']] ?? 0;
        }
        if ($list) {
            return ['code' => ErrorCode::SUCCESS, 'data' => $list];
        }
        return ['code' => ErrorCode::SERVER_ERROR];
    }

    /**
     * 计算指定分类下商品数量
     * @param array $cateIdsArr
     * @param $shopType
     */
    public function calculateNumOfGoods(array $cateIdsArr, $shopType)
    {
        if($shopType){
            $goodsCount = $this->goodsModel::query()->whereIn('crd_cate_id', $cateIdsArr)
                ->where(['is_deleted' => 0, 'is_next_day' => '1'])
                ->selectRaw('COUNT(*) as total,crd_cate_id as cate_id')
                ->groupBy(['crd_cate_id'])
                ->get()->toArray();
        }else{
            $goodsCount = $this->goodsModel::query()->whereIn('cate_id', $cateIdsArr)
                ->where(['is_deleted' => 0,'is_today' => '1'])
                ->selectRaw('COUNT(*) as total,cate_id')
                ->groupBy(['cate_id'])->get()->toArray();
        }
        $goodsCountArr = array_column($goodsCount, 'total', 'cate_id');

        return $goodsCountArr;
    }
    /**
     * 龙收银分类
     * @return array
     */
    public function lsyClassName(){
        $list = ShopLsyGoodsInfoModel::query()->select(['itemClassName as lsy_class_name'])->distinct()->get()->toArray();
        if ($list) {
            return ['code' => ErrorCode::SUCCESS, 'data' => $list];
        }
        return ['code' => ErrorCode::SERVER_ERROR];
    }
    /**分类列表api
     * @param array $where
     * @param array|string[] $field
     * @return array
     */
    public function getCategoryList(array $where, array $field = ['*'], $shopType = null) //要废弃
    {
        $redis = $this->resourceRedis;
        if($shopType){
            //次日达
            $data = $redis->hGet('category:timelybak','resource');
        }else{
            //普通商城
            $data = $redis->hGet('category:overnightbak','resource');
        }
        if($data){
            return ['code' => ErrorCode::SUCCESS, 'data' => json_decode($data)];
        }
        if($shopType){
            $list = $this->crdCategoryModel::query()->where($where)->select($field)->orderBy('sort', 'asc')->get();
            $redis -> hSet('category:timelybak', 'resource', json_encode($list));
        }else{
            $list = $this->categoryModel::query()->where($where)->select($field)->orderBy('sort', 'asc')->get();
            $redis -> hSet('category:overnightbak', 'resource', json_encode($list));
        }
        if ($list) {
            return ['code' => ErrorCode::SUCCESS, 'data' => $list];
        }
        return ['code' => ErrorCode::NOT_EXIST];
    }

    /**
     * @param int $id
     *
     * @return array
     */
    public function getInfoById(int $id, $shopType)
    {
        if($shopType){
            //次日达
            $res = CrdCategoryModel::query()->where('id', $id)->first();
        }else{
            //普通商城
            $res = CategoryModel::query()->where('id', $id)->first();
        }

        if ($res) {
            return ['code' => ErrorCode::SUCCESS, 'data' => $res];
        }
        return ['code' => ErrorCode::NOT_EXIST];
    }

    /**
     * @param array $params
     *
     * @return array
     */
    public function add(array $params)
    {
        $shopType = $params['shop_type'] ?? null;
        if($shopType){
            //次日达商城
            $res = CrdCategoryModel::create($params);
            $this->resourceRedis->hDel('category:overnight','resource');
        }else{
            //及时达商城
            $res = CategoryModel::create($params);
            $this->resourceRedis->hDel('category:timely','resource');
        }
        if ($res) {
            return ['code' => ErrorCode::SUCCESS, 'data' => $res, 'info' => ['target_id' => $res -> id]];
        }
        return ['code' => ErrorCode::NOT_IN_FORCE];
    }

    /**
     * @param array $params
     *
     * @return array
     */
    public function update(array $params)
    {
        $shopType = $params['shop_type'] ?? null;
        if($shopType){
            unset($params['shop_type']);
            //次日达商城
            $res = CrdCategoryModel::where(['id' => $params['id']])->update($params);
            $this->resourceRedis->hDel('category:overnight','resource');
        }else{
            //及时达商城
            $res = CategoryModel::where(['id' => $params['id']])->update($params);
            $this->resourceRedis->hDel('category:timely','resource');
        }
        if ($res) {
            return ['code' => ErrorCode::SUCCESS, 'data' => $res, 'info' => ['target_id' => $params['id']]];
        }
        return ['code' => ErrorCode::NOT_IN_FORCE];
    }

    /**
     * @param int $id
     *
     * @return array
     */
    public function delete(int $id, $shopType)
    {
        if($shopType){
            //次日达商城
            $hasGoods = GoodsModel::where(['crd_cate_id' => $id,'is_deleted' => 0])->first();
            if ($hasGoods) {
                return ['code' => ErrorCode::CATEGORY_DELETE];
            }
            $res = CrdCategoryModel::where('id', $id)->update([
                'is_deleted' => 1
            ]);
            if ($res) {
                $this->resourceRedis->hDel('category:overnight','resource');
                return ['code' => ErrorCode::SUCCESS, 'data' => $res, 'info' => ['target_id' => $id]];
            }
        }else{
            //普通商城
            $hasGoods = GoodsModel::where(['cate_id' => $id,'is_deleted' => 0])->first();
            if ($hasGoods) {
                return ['code' => ErrorCode::CATEGORY_DELETE];
            }
            $res = CategoryModel::where('id', $id)->update([
                'is_deleted' => 1
            ]);
            if ($res) {
                $this->resourceRedis->hDel('category:timely','resource');
                return ['code' => ErrorCode::SUCCESS, 'data' => $res, 'info' => ['target_id' => $id]];
            }
        }

        return ['code' => ErrorCode::NOT_IN_FORCE];
    }

    /**
     * @param int $id
     * @param null $shopType
     *
     * @return array
     */
    public function editHome(int $id, $shopType = null)
    {
        if($shopType){
            //次日达
            $data = CrdCategoryModel::query()->find($id);
        }else{
            //普通商城
            $data = CategoryModel::query()->find($id);
        }
        if (!$data) {
            return ['code' => ErrorCode::NOT_EXIST];
        }
        if ($data->is_home == 1) {
            $data->is_home = 0;
            $operationResults = '隐藏';
        } else {
            $data->is_home = 1;
            $operationResults = '显示';
        }
        $res = $data->save();

        if ($res) {
            if($shopType){
                $this->resourceRedis->hDel('category:overnight','resource');
            }else{
                $this->resourceRedis->hDel('category:timely','resource');
            }
            return ['code' => ErrorCode::SUCCESS, 'data' => $res, 'info' => ['target_id' => $id, 'operation_results' => $operationResults]];
        }
        return ['code' => ErrorCode::NOT_IN_FORCE];
    }

    /**
     * @param string|null $id
     *
     * @return array
     */
    public function editManySort(string $id = null, $shopType = null)
    {
        if (!$id) {
            return ['code' => ErrorCode::SYSTEM_INVALID];
        }
        try {
            $arr = explode(',', $id);
            $keyAndVal = [];
            foreach ($arr as $key => $val) {
                $cate_arr = explode('&', $val);
                $keyAndVal[$cate_arr[0]] = $cate_arr[1];
            }
            $ids = implode(',', array_keys($keyAndVal));

            if($shopType){
                $sql = "UPDATE store_crd_goods_cate SET sort = CASE id ";
            }else{
                $sql = "UPDATE store_goods_cate SET sort = CASE id ";
            }
            foreach ($keyAndVal as $id => $myvalue) {
                $sql .= sprintf("WHEN %d THEN %d ", $id, $myvalue);
            }
            $sql .= "END WHERE id IN ($ids)";
            $res = Db::update($sql);
            if (!$res) {
                throw new \Exception('操作失败', ErrorCode::NOT_IN_FORCE);
            }
        } catch (\Exception $e) {
            return ['code' => ErrorCode::NOT_IN_FORCE];
        }
        $this->resourceRedis->hDel('category:timely','resource');
        return ['code' => ErrorCode::SUCCESS, 'data' => [], 'info' => ['target_id' => $id]];
    }

    /**
     * 及时达分类
     * @return array
     */
    public function getCateNameToIdKey()
    {
        return CategoryModel::query()->where('is_deleted', 0)->pluck('title', 'id')->toArray();
    }

    /**app分类列表
     * @param array $where
     * @param array|string[] $field
     * @return array
     */
    public function getAppCategoryList(array $where, array $field = ['*'])
    {
        $redis = $this->resourceRedis;
            //次日达
            $data = $redis->hGet('category:timelybak','resource');
        if($data){
            return ['code' => ErrorCode::SUCCESS, 'data' => json_decode($data)];
        }
        $list = $this->crdCategoryModel::query()->where($where)->select($field)->orderBy('sort', 'asc')->get();
        $redis -> hSet('category:timelybak', 'resource', json_encode($list));
        if ($list) {
            return ['code' => ErrorCode::SUCCESS, 'data' => $list];
        }
        return ['code' => ErrorCode::NOT_EXIST];
    }
}
